package com.nx.platform.es.system.db;

import com.google.common.collect.Range;
import com.nx.arch.rdb.sharding.api.ShardingValue;
import com.nx.arch.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 订单表按订单id分表算法
 * @author
 *
 */
public class TradeTableShardingByOrderIdAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {

    @Override
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        Long orderId = shardingValue.getValue();
        Integer tableCount = orderId.intValue() >> 14 & 0xff % 8;
        return chooseTable(availableTargetNames, tableCount.longValue());
    }

    @Override
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        for (Long value : shardingValue.getValues()) {
            Integer tableCount = value.intValue() >> 14 & 0xff % 8;
            result.add(chooseTable(availableTargetNames, tableCount.longValue()));
        }
        return result;
    }

    @Override
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,
            ShardingValue<Long> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        Range<Long> range = shardingValue.getValueRange();
        for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
            Integer tableCount = i.intValue() >> 14 & 0xff % 8;
            result.add(chooseTable(availableTargetNames, tableCount.longValue()));
        }
        return result;
    }
    private String chooseTable(Collection<String> availableTargetNames, Long value) {
        for (String each : availableTargetNames) {
            if (each.endsWith("_" + value)) {
                return each;
            }
        }
        throw new UnsupportedOperationException();
    }
}
